/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Extractor.

    Maxsi Extractor is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Extractor is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Extractor.  If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiExtractorContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiExtractorContributors.h. For more information please see
	MaxsiExtractorContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]


	MaxsiExtractor.exe
	A self-extracting application able to store a series of files inside it
	and able to extract these files to the current working directory, run the
	files, and once done, delete all the files.

	Append.cpp
	A system for embedding files into MaxsiExtractor.exe

****************************************************************************/

#include "MaxsiEngine.h"
#include <io.h>
#include <direct.h>
#include <iostream> 
#include <fcntl.h>
#include <SYS\Stat.h>
#include "Main.h" 
#include "UI.h" 
#include "Data.h" 


bool Append(const char* AppendPath)
{
	char*	CurrentDirectory	=	GetWorkingDirectory();

	__int64 FileSize;
	int		fh;
	char*	AllocatedBuffer = 0;
	bool	CustomAppendPath = false;

	cout << AppendPath;

	// First copy the file into memory
	_sopen_s(&fh,AppendPath,O_BINARY | O_RDONLY,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	
	if (fh  == -1)
	{	
		CustomAppendPath = true;
		size_t AppendPath_tmp_size = strlen(CurrentDirectory)+strlen(AppendPath)+1;
		char* AppendPath_tmp = new char[AppendPath_tmp_size];
		strcpy_s(AppendPath_tmp,AppendPath_tmp_size,CurrentDirectory);
		strcat_s(AppendPath_tmp,AppendPath_tmp_size,AppendPath);

		AppendPath = AppendPath_tmp;
		
		_sopen_s(&fh,AppendPath,O_BINARY | O_RDONLY,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	}
	if (fh  == -1)
	{	
		string Error = "Couldn't open ";
		Error+=string(AppendPath);
		Error+=string(" for Binary Reading, aborting.");
		MessageBoxA(NULL,Error.c_str(),"MaxsiExtractor",0);
	}
	else
	{
		FileSize = _filelength(fh);

		AllocatedBuffer = new char[FileSize+1];

		cout << "Loading " << FileSize << " bytes...\n\n";

		_read(fh,AllocatedBuffer,FileSize);
		AllocatedBuffer[FileSize+1] = 0;
		_close(fh);

		char SeekMe[16];
		SeekMe[0] = 'A';
		SeekMe[1] = 'p';
		SeekMe[2] = 'p';
		SeekMe[3] = 'e';
		SeekMe[4] = 'n';
		SeekMe[5] = 'd';
		SeekMe[6] = 'e';
		SeekMe[7] = 'd';
		SeekMe[8] = ' ';
		SeekMe[9] = '=';
		SeekMe[10] = ' ';
		SeekMe[11] = 't';
		SeekMe[12] = 'r';
		SeekMe[13] = 'u';
		SeekMe[14] = 'e';

		size_t AppendLocation = FindStringEx(AllocatedBuffer,FileSize,SeekMe,14);

		if (AppendLocation == -1)
		{
			cout << "Editing file to mark appending is done...\n";
			SeekMe[11] = 'f';
			SeekMe[12] = 'a';
			SeekMe[13] = 'l';
			SeekMe[14] = 's';
			SeekMe[15] = 'e';
			AppendLocation = FindStringEx(AllocatedBuffer,FileSize,SeekMe,15);
			if ( AppendLocation == -1 )
			{
				MessageBoxA(NULL,"Error: Couldn't locate the mark descriping whether this file is appended or not.\n","MaxsiExtractor",0);
			}
			else
			{
				cout << "Found appending mark at " << AppendLocation << "\n";
			}
			char* ReplaceWith = "true";

			strcpy_s(AllocatedBuffer+AppendLocation+11,strlen(ReplaceWith)+1,ReplaceWith);
			
			cout << "Saving file with .tmp as extension ...\n";

			char* AppendPath_Ex = BuildString(2,AppendPath,".tmp");

			_sopen_s(&fh,AppendPath_Ex, _O_CREAT | O_TRUNC | O_BINARY | O_WRONLY, _SH_DENYNO, _S_IREAD | _S_IWRITE);

			delete AppendPath_Ex;

			__int64 InvalidLocation = -1;

			_write(fh,AllocatedBuffer,FileSize);
			_write(fh,&InvalidLocation,sizeof(__int64));
			_close(fh);

		}
		else
		{
			cout << "File is appended @ " << AppendLocation << "\n\n";
			cout << AllocatedBuffer + AppendLocation;
		}
	}
	if (CustomAppendPath) { delete AppendPath; }
	delete CurrentDirectory;

	return true;
}